diff --git a/src/diskusagewidget.cpp b/src/diskusagewidget.cpp index 938d29f..87dd69f 100644 --- a/src/diskusagewidget.cpp +++ b/src/diskusagewidget.cpp @@ -85,20 +85,34 @@ void DiskUsageWidget::setupUI() m_mediaBar = new DiskUsageBar(); m_othersBar = new DiskUsageBar(); m_freeBar = new DiskUsageBar(); + + m_systemBar->setStyleSheet( + " background-color: #a1384d; border: 1px solid" + "#e64a5b; padding: 0; margin: 0; border-top-left-radius: 3px; " + "border-bottom-left-radius: 3px; "); + m_appsBar->setStyleSheet("background-color: #4f869f; border: 1px solid " + "#63b4da; padding: 0; margin: 0; "); + m_mediaBar->setStyleSheet("background-color: #2ECC71; " + "border: none; padding: 0; margin: 0; "); + m_othersBar->setStyleSheet("background-color: #a28729; border: 1px solid " + "#c4a32d; padding: 0; margin: 0; "); + m_freeBar->setStyleSheet( + "background-color: #6e6d6d; border: 1px solid " + "#4f4f4f; padding: 0; margin: 0; border-top-right-radius: 3px; " + "border-bottom-right-radius: 3px; "); + #else m_systemBar = new QWidget(); m_appsBar = new QWidget(); m_mediaBar = new QWidget(); m_othersBar = new QWidget(); m_freeBar = new QWidget(); -#endif // required for tooltips to have default styling m_systemBar->setObjectName("systemBar"); m_appsBar->setObjectName("appsBar"); m_mediaBar->setObjectName("mediaBar"); m_othersBar->setObjectName("othersBar"); m_freeBar->setObjectName("freeBar"); - // Set colors m_systemBar->setStyleSheet( "QWidget#systemBar { background-color: #a1384d; border: 1px solid" @@ -116,6 +130,7 @@ void DiskUsageWidget::setupUI() "QWidget#freeBar { background-color: #474747; border: 1px solid " "#4f4f4f; padding: 0; margin: 0; border-top-right-radius: 3px; " "border-bottom-right-radius: 3px; }"); +#endif m_diskBarLayout->addWidget(m_systemBar); m_diskBarLayout->addWidget(m_appsBar); @@ -220,11 +235,20 @@ void DiskUsageWidget::updateUI() m_diskBarLayout->setStretchFactor(m_freeBar, freeWidth); // Hide segments with zero usage - // m_systemBar->setVisible(m_systemUsage > 0); - // m_appsBar->setVisible(m_appsUsage > 0); - // m_mediaBar->setVisible(m_mediaUsage > 0); - // m_othersBar->setVisible(m_othersUsage > 0); - // m_freeBar->setVisible(m_freeSpace > 0); + m_systemBar->setVisible(m_systemUsage > 0); + m_systemLabel->setVisible(m_systemUsage > 0); + + m_appsBar->setVisible(m_appsUsage > 0); + m_appsLabel->setVisible(m_appsUsage > 0); + + m_mediaBar->setVisible(m_mediaUsage > 0); + m_mediaLabel->setVisible(m_mediaUsage > 0); + + m_othersBar->setVisible(m_othersUsage > 0); + m_othersLabel->setVisible(m_othersUsage > 0); + + m_freeBar->setVisible(m_freeSpace > 0); + m_freeLabel->setVisible(m_freeSpace > 0); // Format sizes for display auto formatSize = [](uint64_t bytes) -> QString { diff --git a/src/main.cpp b/src/main.cpp index 55e82ff..6553d19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,6 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); #ifdef WIN32 - // This setup MUST be done before the QApplication object is created. QString appPath = QCoreApplication::applicationDirPath(); QString gstPluginPath = QDir::toNativeSeparators(appPath + "/gstreamer-1.0"); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f4e8154..a3c163d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,6 +1,5 @@ #include "mainwindow.h" #include "./ui_mainwindow.h" -#include "customtabwidget.h" #include "detailwindow.h" #include "ifusediskunmountbutton.h" #include "ifusemanager.h" @@ -24,6 +23,7 @@ #include "appcontext.h" #include "settingsmanager.h" #include +#include #include #include #include @@ -121,16 +121,15 @@ MainWindow::MainWindow(QWidget *parent) // setWindowIcon(QIcon(":/resources/icons/icon.png")); // Create custom tab widget - m_customTabWidget = new CustomTabWidget(this); - m_customTabWidget->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, - false); + m_ZTabWidget = new ZTabWidget(this); + m_ZTabWidget->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false); setContentsMargins(0, 0, 0, 0); #ifdef __APPLE__ setupMacOSWindow(this); setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false); #endif - setCentralWidget(m_customTabWidget); + setCentralWidget(m_ZTabWidget); // Create device manager and stacked widget for main tab m_mainStackedWidget = new QStackedWidget(); @@ -165,18 +164,16 @@ MainWindow::MainWindow(QWidget *parent) connect(m_deviceManager, &DeviceManagerWidget::updateNoDevicesConnected, this, &MainWindow::updateNoDevicesConnected); - // Add tabs with icons - QIcon deviceIcon(":/resources/icons/MdiLightningBolt.png"); - m_customTabWidget->addTab(m_mainStackedWidget, deviceIcon, "iDevice"); - m_customTabWidget->addTab(AppsWidget::sharedInstance(), "Apps"); - m_customTabWidget->addTab(new ToolboxWidget(this), "Toolbox"); + m_ZTabWidget->addTab(m_mainStackedWidget, "iDevice"); + m_ZTabWidget->addTab(AppsWidget::sharedInstance(), "Apps"); + m_ZTabWidget->addTab(new ToolboxWidget(this), "Toolbox"); auto *jailbrokenWidget = new JailbrokenWidget(this); - m_customTabWidget->addTab(jailbrokenWidget, "Jailbroken"); - m_customTabWidget->finalizeStyles(); + m_ZTabWidget->addTab(jailbrokenWidget, "Jailbroken"); + m_ZTabWidget->finalizeStyles(); // connect( - // m_customTabWidget, &CustomTabWidget::currentChanged, this, + // m_ZTabWidget, &ZTabWidget::currentChanged, this, // [this, jailbrokenWidget](int index) { // if (index == 3) { // Jailbroken tab // jailbrokenWidget->initWidget(); diff --git a/src/mainwindow.h b/src/mainwindow.h index a6c2de9..ffc7c9a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -2,10 +2,10 @@ #define MAINWINDOW_H #include "ZDownloader.h" #include "ZUpdater.h" -#include "customtabwidget.h" #include "devicemanagerwidget.h" #include "iDescriptor.h" #include "libirecovery.h" +#include "ztabwidget.h" #include #include #include @@ -25,6 +25,7 @@ public: static MainWindow *sharedInstance(); MainWindow(QWidget *parent = nullptr); ~MainWindow(); + ZUpdater *m_updater = nullptr; public slots: void updateNoDevicesConnected(); @@ -32,10 +33,9 @@ private: void createMenus(); Ui::MainWindow *ui; - CustomTabWidget *m_customTabWidget; + ZTabWidget *m_ZTabWidget; DeviceManagerWidget *m_deviceManager; QStackedWidget *m_mainStackedWidget; QLabel *m_connectedDeviceCountLabel; - ZUpdater *m_updater = nullptr; }; #endif // MAINWINDOW_H diff --git a/src/platform/macos.mm b/src/platform/macos.mm index bed7726..fd1e259 100644 --- a/src/platform/macos.mm +++ b/src/platform/macos.mm @@ -13,15 +13,31 @@ void setupMacOSWindow(QMainWindow *window) NSView *nativeView = reinterpret_cast(window->winId()); NSWindow *nativeWindow = [nativeView window]; - + [nativeWindow setMovableByWindowBackground:YES]; if (!nativeWindow) { qWarning() << "setupMacOSWindow: native window is null"; return; } + // // Force dark mode + // nsWindow.overrideUserInterfaceStyle = NSUserInterfaceStyleDark; + + // Force light mode + // if (@available(macOS 10.14, *)) { + // [nativeWindow + // setAppearance:[NSAppearance + // appearanceNamed:NSAppearanceNameAqua]]; + // } else { + // // Fallback: no-op on older macOS versions + // } + // nativeWindow.overrideUserInterfaceStyle = NSUserInterfaceStyleLight; + + // // Reset to follow system (default) + // nsWindow.overrideUserInterfaceStyle = NSUserInterfaceStyleUnspecified; + qDebug() << "Setting up macOS window styles"; - window->setUnifiedTitleAndToolBarOnMac(true); + // window->setUnifiedTitleAndToolBarOnMac(true); [nativeWindow setStyleMask:[nativeWindow styleMask] | NSWindowStyleMaskFullSizeContentView | diff --git a/src/settingswidget.cpp b/src/settingswidget.cpp index 2adce92..be0f280 100644 --- a/src/settingswidget.cpp +++ b/src/settingswidget.cpp @@ -1,4 +1,5 @@ #include "settingswidget.h" +#include "mainwindow.h" #include "settingsmanager.h" #include #include @@ -63,13 +64,6 @@ void SettingsWidget::setupUI() m_autoUpdateCheck = new QCheckBox("Automatically check for updates"); generalLayout->addWidget(m_autoUpdateCheck); - m_autoRaiseWindow = - new QCheckBox("Auto-raise main window on device connection"); - generalLayout->addWidget(m_autoRaiseWindow); - - m_switchToNewDevice = new QCheckBox("Switch to newly connected device"); - generalLayout->addWidget(m_switchToNewDevice); - // Theme selection auto *themeLayout = new QHBoxLayout(); themeLayout->addWidget(new QLabel("Theme:")); @@ -92,6 +86,13 @@ void SettingsWidget::setupUI() auto *deviceGroup = new QGroupBox("Device Connection"); auto *deviceLayout = new QVBoxLayout(deviceGroup); + m_autoRaiseWindow = + new QCheckBox("Auto-raise main window on device connection"); + deviceLayout->addWidget(m_autoRaiseWindow); + + m_switchToNewDevice = new QCheckBox("Switch to newly connected device"); + deviceLayout->addWidget(m_switchToNewDevice); + // Connection timeout auto *timeoutLayout = new QHBoxLayout(); timeoutLayout->addWidget(new QLabel("Connection Timeout:")); @@ -195,16 +196,15 @@ void SettingsWidget::onBrowseButtonClicked() void SettingsWidget::onCheckUpdatesClicked() { - // TODO: Implement update checking logic m_checkUpdatesButton->setText("Checking..."); m_checkUpdatesButton->setEnabled(false); + MainWindow::sharedInstance()->m_updater->checkForUpdates(); + // Simulate check (replace with actual update check) QTimer::singleShot(2000, this, [this]() { m_checkUpdatesButton->setText("Check for Updates"); m_checkUpdatesButton->setEnabled(true); - QMessageBox::information(this, "Updates", - "You are running the latest version."); }); } diff --git a/src/welcomewidget.cpp b/src/welcomewidget.cpp index 3e9a61d..79a6a44 100644 --- a/src/welcomewidget.cpp +++ b/src/welcomewidget.cpp @@ -1,4 +1,5 @@ #include "welcomewidget.h" +#include "iDescriptor-ui.h" #include "responsiveqlabel.h" #include #include @@ -68,6 +69,10 @@ void WelcomeWidget::setupUI() createStyledLabel("Found an issue? Report it on GitHub", 12, false); m_githubLabel->setAlignment(Qt::AlignCenter); m_githubLabel->setCursor(Qt::PointingHandCursor); + connect(m_githubLabel, &ZLabel::clicked, this, []() { + QDesktopServices::openUrl( + QUrl("https://github.com/uncor3/iDescriptor")); + }); // Make it look like a link QPalette githubPalette = m_githubLabel->palette(); @@ -84,13 +89,13 @@ void WelcomeWidget::setupUI() m_mainLayout->addStretch(1); // Set minimum size - setMinimumSize(600, 500); + // setMinimumSize(600, 500); } -QLabel *WelcomeWidget::createStyledLabel(const QString &text, int fontSize, +ZLabel *WelcomeWidget::createStyledLabel(const QString &text, int fontSize, bool isBold) { - QLabel *label = new QLabel(text); + ZLabel *label = new ZLabel(text); QFont font = label->font(); if (fontSize > 0) { @@ -105,16 +110,3 @@ QLabel *WelcomeWidget::createStyledLabel(const QString &text, int fontSize, return label; } - -bool WelcomeWidget::eventFilter(QObject *watched, QEvent *event) -{ - if (watched == m_githubLabel && event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if (mouseEvent->button() == Qt::LeftButton) { - QDesktopServices::openUrl( - QUrl("https://github.com/uncor3/iDescriptor")); - return true; - } - } - return QWidget::eventFilter(watched, event); -} \ No newline at end of file diff --git a/src/welcomewidget.h b/src/welcomewidget.h index d08c75e..9b7fa92 100644 --- a/src/welcomewidget.h +++ b/src/welcomewidget.h @@ -1,6 +1,7 @@ #ifndef WELCOMEWIDGET_H #define WELCOMEWIDGET_H +#include "iDescriptor-ui.h" #include "responsiveqlabel.h" #include #include @@ -15,20 +16,17 @@ class WelcomeWidget : public QWidget public: explicit WelcomeWidget(QWidget *parent = nullptr); -protected: - bool eventFilter(QObject *watched, QEvent *event) override; - private: void setupUI(); - QLabel *createStyledLabel(const QString &text, int fontSize = 0, + ZLabel *createStyledLabel(const QString &text, int fontSize = 0, bool isBold = false); QVBoxLayout *m_mainLayout; - QLabel *m_titleLabel; - QLabel *m_subtitleLabel; + ZLabel *m_titleLabel; + ZLabel *m_subtitleLabel; ResponsiveQLabel *m_imageLabel; - QLabel *m_instructionLabel; - QLabel *m_githubLabel; + ZLabel *m_instructionLabel; + ZLabel *m_githubLabel; }; #endif // WELCOMEWIDGET_H \ No newline at end of file diff --git a/src/customtabwidget.cpp b/src/ztabwidget.cpp similarity index 62% rename from src/customtabwidget.cpp rename to src/ztabwidget.cpp index c33f594..a9773e7 100644 --- a/src/customtabwidget.cpp +++ b/src/ztabwidget.cpp @@ -1,4 +1,4 @@ -#include "customtabwidget.h" +#include "ztabwidget.h" #include #include #include @@ -6,24 +6,14 @@ #include #include -// CustomTab implementation -CustomTab::CustomTab(const QString &text, QWidget *parent) - : QPushButton(text, parent) +ZTab::ZTab(const QString &text, QWidget *parent) : QPushButton(text, parent) { setCheckable(true); - // setFixedHeight(54); - // setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + setFixedHeight(50); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } -void CustomTab::setIcon(const QIcon &icon) -{ - QPushButton::setIcon(icon); - setIconSize(QSize(20, 20)); -} - -// CustomTabWidget implementation -CustomTabWidget::CustomTabWidget(QWidget *parent) - : QWidget(parent), m_currentIndex(0) +ZTabWidget::ZTabWidget(QWidget *parent) : QWidget(parent), m_currentIndex(0) { m_mainLayout = new QVBoxLayout(this); m_mainLayout->setContentsMargins(0, 0, 0, 0); @@ -31,16 +21,11 @@ CustomTabWidget::CustomTabWidget(QWidget *parent) // Create tab bar container m_tabBar = new QWidget(); - // m_tabBar->setFixedHeight(70); // 54px height + 16px padding + m_tabBar->setFixedHeight(50); + m_tabBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_tabLayout = new QHBoxLayout(m_tabBar); - // m_tabLayout->setContentsMargins(12, 8, 12, 8); m_tabLayout->setSpacing(0); - - // Style the tab bar - m_tabBar->setStyleSheet("QWidget {" - // " background-color: white;" - // " border-radius: 35px;" - "}"); + m_tabLayout->setContentsMargins(0, 0, 0, 0); // Add drop shadow effect QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(); @@ -54,6 +39,8 @@ CustomTabWidget::CustomTabWidget(QWidget *parent) // Create stacked widget for content m_stackedWidget = new QStackedWidget(); + m_stackedWidget->setSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Expanding); // Add widgets to layout m_mainLayout->addWidget(m_tabBar); @@ -62,7 +49,7 @@ CustomTabWidget::CustomTabWidget(QWidget *parent) setupGlider(); } -void CustomTabWidget::setupGlider() +void ZTabWidget::setupGlider() { m_glider = new QWidget(m_tabBar); m_glider->setStyleSheet("QWidget {" @@ -76,19 +63,10 @@ void CustomTabWidget::setupGlider() m_gliderAnimation->setEasingCurve(QEasingCurve::OutCubic); } -int CustomTabWidget::addTab(QWidget *widget, const QString &label) +int ZTabWidget::addTab(QWidget *widget, const QString &label) { - return addTab(widget, QIcon(), label); -} - -int CustomTabWidget::addTab(QWidget *widget, const QIcon &icon, - const QString &label) -{ - CustomTab *tab = new CustomTab(label, m_tabBar); - if (!icon.isNull()) { - tab->setIcon(icon); - } - connect(tab, &CustomTab::clicked, this, &CustomTabWidget::onTabClicked); + ZTab *tab = new ZTab(label, m_tabBar); + connect(tab, &ZTab::clicked, this, &ZTabWidget::onTabClicked); int index = m_tabs.count(); m_tabs.append(tab); m_widgets.append(widget); @@ -97,23 +75,10 @@ int CustomTabWidget::addTab(QWidget *widget, const QIcon &icon, m_stackedWidget->addWidget(widget); m_buttonGroup->addButton(tab, index); - // Set first tab as checked by default - if (index == 0) { - tab->setChecked(true); - // Position glider immediately for first tab to prevent shifting - QTimer::singleShot(0, [this, tab]() { - m_glider->setFixedSize(tab->size().width(), 2); - int targetX = tab->pos().x(); - int targetY = tab->pos().y() + tab->size().height() - 2; - m_glider->move(targetX, targetY); - m_glider->show(); - }); - } - return index; } -void CustomTabWidget::setCurrentIndex(int index) +void ZTabWidget::setCurrentIndex(int index) { if (index < 0 || index >= m_tabs.count() || index == m_currentIndex) { return; @@ -128,11 +93,27 @@ void CustomTabWidget::setCurrentIndex(int index) emit currentChanged(index); } -void CustomTabWidget::finalizeStyles() { updateTabStyles(); } +void ZTabWidget::finalizeStyles() +{ + ZTab *tab = m_tabs[0]; + if (tab) { + tab->setChecked(true); + QTimer::singleShot(0, [this, tab]() { + if (tab) { + m_glider->setFixedSize(tab->size().width(), 2); + int targetX = tab->pos().x(); + int targetY = tab->pos().y() + tab->size().height() - 2; + m_glider->move(targetX, targetY); + m_glider->show(); + } + }); + } + updateTabStyles(); +} -int CustomTabWidget::currentIndex() const { return m_currentIndex; } +int ZTabWidget::currentIndex() const { return m_currentIndex; } -QWidget *CustomTabWidget::widget(int index) const +QWidget *ZTabWidget::widget(int index) const { if (index < 0 || index >= m_widgets.count()) { return nullptr; @@ -140,9 +121,9 @@ QWidget *CustomTabWidget::widget(int index) const return m_widgets[index]; } -void CustomTabWidget::onTabClicked() +void ZTabWidget::onTabClicked() { - CustomTab *clickedTab = qobject_cast(sender()); + ZTab *clickedTab = qobject_cast(sender()); if (!clickedTab) return; @@ -152,12 +133,12 @@ void CustomTabWidget::onTabClicked() } } -void CustomTabWidget::animateGlider(int index) +void ZTabWidget::animateGlider(int index) { if (index < 0 || index >= m_tabs.count()) return; - CustomTab *targetTab = m_tabs[index]; + ZTab *targetTab = m_tabs[index]; if (!targetTab) return; @@ -171,7 +152,8 @@ void CustomTabWidget::animateGlider(int index) // Position glider at the bottom of the target tab int targetX = targetTabPos.x(); int targetY = - targetTabPos.y() + targetTabSize.height() + 6; // Position at bottom + // targetTabPos.y() + targetTabSize.height() + 6; // Position at bottom + targetTabPos.y() + targetTabSize.height() - 2; // Position at bottom m_gliderAnimation->stop(); m_gliderAnimation->setStartValue(m_glider->pos()); @@ -179,12 +161,12 @@ void CustomTabWidget::animateGlider(int index) m_gliderAnimation->start(); } -void CustomTabWidget::updateTabStyles() +void ZTabWidget::updateTabStyles() { for (int i = 0; i < m_tabs.count(); ++i) { - CustomTab *tab = m_tabs[i]; + ZTab *tab = m_tabs[i]; if (tab->isChecked()) { - tab->setStyleSheet("CustomTab {" + tab->setStyleSheet("ZTab {" " color: #185ee0;" // " color: #d7e1f4ff;" " font-weight: 500;" @@ -193,11 +175,11 @@ void CustomTabWidget::updateTabStyles() " outline: none;" " background-color: transparent;" "}" - "CustomTab:hover {" + "ZTab:hover {" " background-color: transparent;" "}"); } else { - tab->setStyleSheet("CustomTab {" + tab->setStyleSheet("ZTab {" " color: #666;" // " color: #2b5693;" " font-weight: 500;" @@ -206,7 +188,7 @@ void CustomTabWidget::updateTabStyles() " outline: none;" " background-color: transparent;" "}" - "CustomTab:hover {" + "ZTab:hover {" " color: #185ee0;" " background-color: transparent;" "}"); @@ -214,13 +196,11 @@ void CustomTabWidget::updateTabStyles() } } -void CustomTabWidget::resizeEvent(QResizeEvent *event) +// Update glider position when widget is resized +void ZTabWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); - - // Update glider position when widget is resized if (m_currentIndex >= 0 && m_currentIndex < m_tabs.count()) { - // Use a timer to ensure layout has been updated - QTimer::singleShot(0, [this]() { animateGlider(m_currentIndex); }); + animateGlider(m_currentIndex); } } \ No newline at end of file diff --git a/src/customtabwidget.h b/src/ztabwidget.h similarity index 72% rename from src/customtabwidget.h rename to src/ztabwidget.h index 4f7efd3..0e8addc 100644 --- a/src/customtabwidget.h +++ b/src/ztabwidget.h @@ -1,5 +1,5 @@ -#ifndef CUSTOMTABWIDGET_H -#define CUSTOMTABWIDGET_H +#ifndef ZTABWIDGET_H +#define ZTABWIDGET_H #include #include @@ -11,24 +11,23 @@ #include #include -class CustomTab : public QPushButton +class ZTab : public QPushButton { Q_OBJECT public: - explicit CustomTab(const QString &text, QWidget *parent = nullptr); + explicit ZTab(const QString &text, QWidget *parent = nullptr); void setIcon(const QIcon &icon); }; -class CustomTabWidget : public QWidget +class ZTabWidget : public QWidget { Q_OBJECT public: - explicit CustomTabWidget(QWidget *parent = nullptr); + explicit ZTabWidget(QWidget *parent = nullptr); void finalizeStyles(); int addTab(QWidget *widget, const QString &label); - int addTab(QWidget *widget, const QIcon &icon, const QString &label); void setCurrentIndex(int index); int currentIndex() const; QWidget *widget(int index) const; @@ -50,7 +49,7 @@ private: QButtonGroup *m_buttonGroup; QWidget *m_glider; QPropertyAnimation *m_gliderAnimation; - QList m_tabs; + QList m_tabs; QList m_widgets; int m_currentIndex; @@ -59,4 +58,4 @@ private: void updateTabStyles(); }; -#endif // CUSTOMTABWIDGET_H \ No newline at end of file +#endif // ZTABWIDGET_H \ No newline at end of file