File indexing completed on 2024-05-12 16:39:35
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2012 Jarosław Staniek <staniek@kde.org> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this program; see the file COPYING. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kexi.h" 0021 #include "KexiRecentProjects.h" 0022 #include "KexiMainWindowIface.h" 0023 #include "kexipartmanager.h" 0024 #include <KexiIcon.h> 0025 0026 #include <KDb> 0027 #include <KDbMessageHandler> 0028 #include <KDbDriverManager> 0029 #include <KDbDriverMetaData> 0030 #include <KDbUtils> 0031 0032 #include <KAboutData> 0033 #include <KMessageBox> 0034 #include <KIconTheme> 0035 0036 #include <QPixmap> 0037 #include <QPixmapCache> 0038 #include <QLabel> 0039 #include <QMimeDatabase> 0040 #include <QMimeType> 0041 #include <QFileInfo> 0042 0043 using namespace Kexi; 0044 0045 //! used for speedup 0046 //! @internal 0047 class KexiInternal 0048 { 0049 public: 0050 static KexiInternal *_int; 0051 0052 KexiInternal() 0053 : connset(0) 0054 { 0055 } 0056 ~KexiInternal() { 0057 delete connset; 0058 } 0059 0060 static KexiInternal* self() { 0061 static bool created = false; 0062 if (!created) { 0063 _int = new KexiInternal; 0064 created = true; 0065 } 0066 return _int; 0067 } 0068 0069 static void destroy() { 0070 delete _int; 0071 _int = 0; 0072 } 0073 0074 KexiDBConnectionSet* connset; 0075 KexiRecentProjects recentProjects; 0076 KexiDBConnectionSet recentConnections; 0077 KDbDriverManager driverManager; 0078 KexiPart::Manager partManager; 0079 }; 0080 0081 KexiInternal *KexiInternal::_int = 0; 0082 0083 KexiDBConnectionSet& Kexi::connset() 0084 { 0085 //delayed 0086 if (!KexiInternal::self()->connset) { 0087 //load stored set data, OK? 0088 KexiInternal::self()->connset = new KexiDBConnectionSet(); 0089 KexiInternal::self()->connset->load(); 0090 } 0091 return *KexiInternal::self()->connset; 0092 } 0093 0094 KexiRecentProjects* Kexi::recentProjects() 0095 { 0096 return &KexiInternal::self()->recentProjects; 0097 } 0098 0099 KDbDriverManager& Kexi::driverManager() 0100 { 0101 return KexiInternal::self()->driverManager; 0102 } 0103 0104 KexiPart::Manager& Kexi::partManager() 0105 { 0106 return KexiInternal::self()->partManager; 0107 } 0108 0109 void Kexi::deleteGlobalObjects() 0110 { 0111 KexiInternal::self()->destroy(); 0112 } 0113 0114 //temp 0115 0116 bool _tempShowMacros = true; 0117 bool& Kexi::tempShowMacros() 0118 { 0119 #ifndef KEXI_MACROS_SUPPORT 0120 _tempShowMacros = false; 0121 #endif 0122 return _tempShowMacros; 0123 } 0124 0125 bool _tempShowScripts = true; 0126 bool& Kexi::tempShowScripts() 0127 { 0128 #ifndef KEXI_SCRIPTS_SUPPORT 0129 _tempShowScripts = false; 0130 #endif 0131 return _tempShowScripts; 0132 } 0133 0134 //-------------------------------------------------------------------------------- 0135 QString Kexi::nameForViewMode(ViewMode mode, bool withAmpersand) 0136 { 0137 if (!withAmpersand) 0138 return Kexi::nameForViewMode(mode, true).remove('&'); 0139 0140 if (mode == NoViewMode) 0141 return xi18n("&No View"); 0142 else if (mode == DataViewMode) 0143 return xi18n("&Data View"); 0144 else if (mode == DesignViewMode) 0145 return xi18n("D&esign View"); 0146 else if (mode == TextViewMode) 0147 return xi18n("&Text View"); 0148 0149 return xi18n("&Unknown"); 0150 } 0151 0152 //-------------------------------------------------------------------------------- 0153 QString Kexi::iconNameForViewMode(ViewMode mode) 0154 { 0155 const char *const id = 0156 (mode == DataViewMode) ? KexiIconNameCStr("data-view") : 0157 (mode == DesignViewMode) ? KexiIconNameCStr("design-view") : 0158 (mode == TextViewMode) ? KexiIconNameCStr("sql-view"): 0159 0; 0160 0161 return QLatin1String(id); 0162 } 0163 0164 //-------------------------------------------------------------------------------- 0165 0166 ObjectStatus::ObjectStatus() 0167 : m_resultable(0), m_msgHandler(0) 0168 { 0169 } 0170 0171 ObjectStatus::ObjectStatus(const QString& message, const QString& description) 0172 : m_resultable(0), m_msgHandler(0) 0173 { 0174 setStatus(message, description); 0175 } 0176 0177 ObjectStatus::ObjectStatus(const KDbResultable* resultable, const QString& message, const QString& description) 0178 : m_resultable(0), m_msgHandler(0) 0179 { 0180 setStatus(resultable, message, description); 0181 } 0182 0183 ObjectStatus::~ObjectStatus() 0184 { 0185 delete m_msgHandler; 0186 } 0187 0188 const ObjectStatus& ObjectStatus::status() const 0189 { 0190 return *this; 0191 } 0192 0193 bool ObjectStatus::error() const 0194 { 0195 return !message.isEmpty() 0196 || (m_resultable && m_resultable->result().isError()); 0197 } 0198 0199 void ObjectStatus::setStatus(const QString& message, const QString& description) 0200 { 0201 m_resultable = 0; 0202 this->message = message; 0203 this->description = description; 0204 } 0205 0206 void ObjectStatus::setStatus(const KDbResultable* resultable, const QString& message, const QString& description) 0207 { 0208 m_resultable = resultable; 0209 this->message = message; 0210 this->description = description; 0211 } 0212 0213 void ObjectStatus::setStatus(KDbResultInfo* resultInfo, const QString& message, const QString& description) 0214 { 0215 if (resultInfo) { 0216 if (message.isEmpty()) { 0217 this->message = resultInfo->message; 0218 } else { 0219 this->message = message + " " + resultInfo->message; 0220 } 0221 0222 if (description.isEmpty()) { 0223 this->description = resultInfo->description; 0224 } else { 0225 this->description = description + " " + resultInfo->description; 0226 } 0227 } else { 0228 setStatus(message, description); 0229 } 0230 } 0231 0232 void ObjectStatus::setStatus(const KDbResultable* resultable, KDbResultInfo* resultInfo, 0233 const QString& message, const QString& description) 0234 { 0235 if (!resultable) 0236 setStatus(resultInfo, message, description); 0237 else if (!resultInfo) 0238 setStatus(resultable, message, description); 0239 else { 0240 setStatus(resultable, message, description); 0241 setStatus(resultInfo, this->message, this->description); 0242 } 0243 } 0244 0245 void ObjectStatus::setStatus(const KDbResult &result, KDbResultInfo* resultInfo, 0246 const QString& message, const QString& description) 0247 { 0248 //! @todo KEXI3 test this 0249 if (!result.isError()) { 0250 if (resultInfo) { 0251 setStatus(resultInfo, message, description); 0252 } else { 0253 setStatus(message, description); 0254 } 0255 } 0256 else { 0257 if (resultInfo) { 0258 KDbResult r = result; 0259 r.prependMessage(message); 0260 r.prependMessage(description); 0261 setStatus(resultInfo, r.messageTitle(), r.message()); 0262 } else { 0263 setStatus(message, description); 0264 } 0265 } 0266 } 0267 0268 void ObjectStatus::clearStatus() 0269 { 0270 message.clear(); 0271 description.clear(); 0272 } 0273 0274 QString ObjectStatus::singleStatusString() const 0275 { 0276 if (message.isEmpty() || description.isEmpty()) 0277 return message; 0278 return message + " " + description; 0279 } 0280 0281 void ObjectStatus::append(const ObjectStatus& otherStatus) 0282 { 0283 if (message.isEmpty()) { 0284 message = otherStatus.message; 0285 description = otherStatus.description; 0286 return; 0287 } 0288 const QString s(otherStatus.singleStatusString()); 0289 if (s.isEmpty()) 0290 return; 0291 if (description.isEmpty()) { 0292 description = s; 0293 return; 0294 } 0295 description = description + " " + s; 0296 } 0297 0298 //! @internal 0299 class ObjectStatusMessageHandler : public KDbMessageHandler 0300 { 0301 public: 0302 explicit ObjectStatusMessageHandler(ObjectStatus *status) 0303 : KDbMessageHandler() 0304 , m_status(status) { 0305 } 0306 virtual ~ObjectStatusMessageHandler() { 0307 } 0308 0309 virtual void showErrorMessage(KDbMessageHandler::MessageType messageType, 0310 const QString &msg, 0311 const QString &details = QString(), 0312 const QString &caption = QString()) override 0313 { 0314 Q_UNUSED(messageType); 0315 Q_UNUSED(caption); 0316 m_status->setStatus(msg, details); 0317 } 0318 0319 virtual void showErrorMessage(const KDbResult& result, 0320 KDbMessageHandler::MessageType messageType = KDbMessageHandler::Error, 0321 const QString& msg = QString(), 0322 const QString& caption = QString()) override 0323 { 0324 Q_UNUSED(messageType); 0325 m_status->setStatus(result, 0, caption, msg); 0326 } 0327 0328 ObjectStatus *m_status; 0329 }; 0330 0331 ObjectStatus::operator KDbMessageHandler*() 0332 { 0333 if (!m_msgHandler) 0334 m_msgHandler = new ObjectStatusMessageHandler(this); 0335 return m_msgHandler; 0336 } 0337 0338 void KEXI_UNFINISHED_INTERNAL(const QString& feature_name, const QString& extra_text, 0339 QString* line1, QString* line2) 0340 { 0341 if (feature_name.isEmpty()) 0342 *line1 = xi18n("This function is not available for version %1 of %2 application.", 0343 QString(KEXI_VERSION_STRING), QString(KEXI_APP_NAME)); 0344 else { 0345 QString feature_name_(feature_name); 0346 *line1 = xi18nc("@info", 0347 "<resource>%1</resource> function is not available for version %2 of %3 application.", 0348 feature_name_.remove('&'), QString(KEXI_VERSION_STRING), QString(KEXI_APP_NAME)); 0349 } 0350 0351 *line2 = extra_text; 0352 } 0353 0354 void KEXI_UNFINISHED(const QString& feature_name, const QString& extra_text) 0355 { 0356 QString line1, line2; 0357 KEXI_UNFINISHED_INTERNAL(feature_name, extra_text, &line1, &line2); 0358 if (!line2.isEmpty()) 0359 line2.prepend("\n"); 0360 KMessageBox::sorry(0, line1 + line2); 0361 } 0362 0363 QLabel *KEXI_UNFINISHED_LABEL(const QString& feature_name, const QString& extra_text) 0364 { 0365 QString line1, line2; 0366 KEXI_UNFINISHED_INTERNAL(feature_name, extra_text, &line1, &line2); 0367 QLabel *label = new QLabel(QLatin1String("<b>") + line1 + QLatin1String("</b><br>") 0368 + line2); 0369 label->setAlignment(Qt::AlignCenter); 0370 label->setWordWrap(true); 0371 label->setAutoFillBackground(true); 0372 label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); 0373 return label; 0374 } 0375 0376 //-------------------------------------------------------------------------------- 0377 0378 QString Kexi::defaultFileBasedDriverIconName() 0379 { 0380 return KexiIconName("file-database"); 0381 } 0382 0383 QIcon Kexi::defaultFileBasedDriverIcon() 0384 { 0385 return QIcon::fromTheme(defaultFileBasedDriverIconName()); 0386 } 0387 0388 QString Kexi::serverIconName() 0389 { 0390 return KexiIconName("network-server-database"); 0391 } 0392 0393 QIcon Kexi::serverIcon() 0394 { 0395 return QIcon::fromTheme(serverIconName()); 0396 } 0397 0398 QString Kexi::appIncorrectlyInstalledMessage() 0399 { 0400 return xi18nc("@info", "<application>%1</application> could have been incorrectly " 0401 "installed or started. The application will be closed.", 0402 QApplication::applicationDisplayName()); 0403 } 0404 0405 QString Kexi::basePathForProject(const KDbConnectionData& connectionData) 0406 { 0407 KDbDriverManager manager; 0408 const KDbDriverMetaData* driverMetaData = manager.driverMetaData(connectionData.driverId()); 0409 if (driverMetaData && driverMetaData->isFileBased()) { 0410 const QFileInfo fileinfo(connectionData.databaseName()); 0411 return fileinfo.path(); 0412 } 0413 return QString(); 0414 } 0415 0416 bool Kexi::isKexiInstance() 0417 { 0418 return KAboutData::applicationData().componentName() == QLatin1String("kexi"); 0419 }